﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace DynamicToolkit
{
    static class XpathHelper
    {
        public static readonly string DateFormat = "yyyy-MM-dd'T'HH:mm:ss'Z'";

        public static string EscapeXpathValue(object value)
        {
            string text = value != null ? value.ToString() ?? string.Empty : string.Empty;

            if (value is DateTime)
            {
                DateTime dt = (DateTime) value;
                return string.Format("'{0}'", FormatDate(dt));
            }
            else if (value is DateTime?)
            {
                DateTime? dt = value as DateTime?;
                return string.Format("'{0}'", dt.HasValue ? FormatDate(dt.Value) : string.Empty);
            }
            else if (IsNumeric(text))
            {
                return text;
            }
            else if (IsBoolean(text))
            {
                return (Convert.ToBoolean(text)) ? "true" : "false";
            }
            else if (!text.Contains("'"))
            {
                return string.Format("'{0}'", text);
            }
            else if (!text.Contains("\""))
            {
                return string.Format("\"{0}\"", text);
            }
            else
            {
                StringBuilder buf = new StringBuilder("concat(");
                string[] tokens = text.Split('\'');
                for (int i = 0; i < tokens.Length; i++)
                {
                    string token = tokens[i];

                    if (i > 0)
                    {
                        buf.Append(",\"'\",");
                    }

                    buf.AppendFormat("\"{0}\"", token);
                }

                buf.Append(")");
                return buf.ToString();
            }
        }

        private static bool IsNumeric(string s)
        {
            if (string.IsNullOrEmpty(s))
            {
                return false;
            }

            double result;
            return double.TryParse(s, out result);
        }

        private static bool IsBoolean(string s)
        {
            if (string.IsNullOrEmpty(s))
            {
                return false;
            }
            
            bool result;
            return bool.TryParse(s, out result);
        }

        private static string FormatDate(DateTime date)
        {
            return date.ToUniversalTime().ToString(DateFormat);
        }
    }
}
